//Body events
caboCity.implement({

	//Initialize body vars
	iniBody: function(){
		this.bodyID = 0;
		this.body = new Array();
	}
	
	//Add new body
	, addNewBody: function(type){
		var b = new body(type);
		
		//Save body information
		this.body[++this.bodyID] = b;
		b.key = this.bodyID;
		
		return b;
	}
	
	//Create new inmigrant
	//@house means the house to go.
	,bCreateInmigrant: function(house, amount){
		var bInm = this.addNewBody(d.b.t.inmigrant);
		bInm.setDestinationBuild(house);
		bInm.setAmountOf('amount', amount);
		bInm.move();
	}
	,checkForNewInmigrants: function(){
		//Number max of spaces that will be ocuped
		var maxFS = this.desirability*this.l(this.hWithFreeSpace);
		
		var getted = 0;
		this.hWithFreeSpace.each(function(h, key){
			if(h && getted != maxFS){
				var fs = (h.atrb.capacity - h.atrb.people);
				var maxInmg = Math.min(fs, 4);
				var nImgr = Math.floor( maxInmg*Math.random() )+1;
				
				var dt = d.emp.month*getted/maxFS;
				(function(coor, ni){
					this.bCreateInmigrant(coor, ni);
				}).delay(dt, this, [h.coor, nImgr]);
				
				this.hWithFreeSpace[key] = null;
				getted++;
			}
		}, this);
	}
	
	//Based on his pre-stored properties for its "configuration".
	, moveBody : function(b){
		//Put body in game
		if(b.recentlycreated) { //First time
			//Create HTML element in its initial position
			var pos = this.p(b.from); //Initial position
			var el = new Element('div', {
				styles: {
					left: pos.x,
					top: pos.y
				}
			});
					
			//Realize movement.
			el.set('morph', {
				duration: 200,
				link: 'cancel',
				transition: 'linear',
				onComplete: this.moveBody.bind(this,b) //Move it!
			});
			
			//Add Element Class
			el.addClass('body').addClass(b.elClass);
			
			el.inject(this.cont);
			b.el = el;
			
			//"First time" ended
			b.recentlycreated = false;
			b.to = b.path.pop();
			this.moveBody(b);
			
			//Exit
			return;
		}
		
		if(b.aPP) b.fPP(); //Bloq-bloq Action
		
		//Decide Next movement START
		//Have destination coor?
		if(b.haveDest){
			//Body arrived to destination coor?
			if(b.to.x==b.dest.x && b.to.y==b.dest.y){
				var h = this.getHouse(b.destBuild);
				b.fActionDest(h);
				console.log("Llegada al destino");
				return;
			}
		}
		//Next movement
		if(b.predPath) { //Predefined path?
			b.from = Object.clone(b.to); //Actual position
			b.to = b.path.pop();
		} else {
			b.from = Object.clone(b.to); //Actual position
			this.moveRandom(b);
		}
		//Decide Next movement END
		
		if(this.isRoad(b.to)){ //Is a correct position?
			
			var from = this.p(b.from);
			var to = this.p(b.to);
			b.el.morph({
				'left' : [from.x-5 , to.x-5] ,
				'top' : [from.y-10 , to.y-10]
			});
		} else {
			//Position error!
			console.log("Position error!");
		}
	}
	
	//Random movement
	, moveRandom: function(b){
		//4 posibilidades
		//  1 
		//2   3
		//  4
		if(!b.dir) b.dir = 0;
		
		var case1 = false;
		var case2 = false;
		var case3 = false;
		var case4 = false;
		
		//Decide new movement except where it came from
		while( !(case1 && case2 && case3 && case4) ){
			var rand = Math.floor(Math.random()*4) +1; //Try to decide next movement
			switch(rand){
				case 1: //Up
					var next = {x: b.from.x, y: b.from.y-1};
					if( b.dir != 1 && this.isRoadTransitable(b.from, next) ) {
						b.dir = 4;
						b.to = Object.clone(next);
						return;
					} else case1 = true;
				case 2: //Right
					var next = {x: b.from.x-1, y: b.from.y};
					if( b.dir != 2 && this.isRoadTransitable(b.from, next) ) {
						b.dir = 3;
						b.to = Object.clone(next);
						return;
					} else case2 = true;
				case 3: //Left
					var next = {x: b.from.x+1, y: b.from.y};
					if( b.dir != 3 && this.isRoadTransitable(b.from, next) ) {
						b.dir = 2;
						b.to = Object.clone(next);
						return;
					} else case3 = true;
				case 4: //Bottom
					var next = {x: b.from.x, y: b.from.y+1};
					if( b.dir != 4 && this.isRoadTransitable(b.from, next) ){
						b.dir = 1;
						b.to = Object.clone(next);
						return;
					} else case4 = true;
			}
		}
		
		//Back to where it came from
		switch(b.dir){
			case 1:
				b.to = {x: b.from.x, y: b.from.y-1};
				if(!this.isRoad(b.to)) break;
				b.dir = 4;
				return;
			case 2:
				b.to = {x: b.from.x-1, y: b.from.y};
				if(!this.isRoad(b.to)) break;
				b.dir = 3;
				return;
			case 3:
				b.to = {x: b.from.x+1, y: b.from.y};
				if(!this.isRoad(b.to)) break;
				b.dir = 2;
				return;
			case 4:
				b.to = {x: b.from.x, y: b.from.y+1};
				if(!this.isRoad(b.to)) break;
				b.dir = 1;
				return;
			default: //Only when it can't be moved
		}
		b.to = b.from;
		
	}
	
	//The next position for body based on the dir var and actual pos.
	, dirToCoor: function(pos, dir){
		switch(dir){
			case 1:
				return {x: pos.x, y: pos.y-1};
			case 2:
				return {x: pos.x-1, y: pos.y};
			case 3:
				return {x: pos.x+1, y: pos.y};
			case 4:
				return {x: pos.x, y: pos.y+1};
		}
	}
	,removeBody: function(b){
		b.remove();
		this.body[b.key] = null;
	}
});

var body = new Class({
	//@type := IDentification of the object definition
	//@recentlycreated := means that the body isn't created yet.
	//@from := the actual position at this moment
	//@to := The next position
	//@destBuild := destination Build Coordinate
	//@dest := destination Coordinate
	//@fActionDest := Function action destination
	//@elClass := Contains body's definition for its element class
	//@aPP := "action Position-Position". True if body have action in each position.
	//@fPP := "function Position-Position". Have the function for execute in each position.
	//@predPath := True if body req. a predefined path to go somewhere.
	//@path := Contains the predefined path.
	//@el := HTML element of the body
	//@key := The identification of the body
	initialize: function(type){
		this.type = type;
		this.recentlycreated = true; //If the body is created
		
		var btl = listBodyTypes[type];
		if(!btl.reqInitPos) this.from = {x: btl.defaultInitPos().x, y: btl.defaultInitPos().y }; //Get the default start position
		else this.from = {x:-1, y:-1}; //The position will be reemplazed in the future.
		
		this.elClass = btl.elClass;
		
		//Body have action bloq by bloq?
		if(btl.reqActionPP){
			this.aPP = true;
			this.fPP = btl.fActionPP;
		} else {
			this.aPP = false;
			this.fPP = null;
		}
		
		//Have predefined path?
		if(btl.reqDestPos){
			this.predPath = true;
			this.haveDest = true;
			this.fActionDest = btl.fActionDest;
		} else {
			this.predPath = false;
			this.haveDest = false;
		}

		this.path = null;
		
		this.dir = null; //Auxiliar.
		this.el = null;
		
		this.endBuild = null; //Coor of the destination build
		this.destCoor = null;
		
		this.services = [];
		this.key = -1;
	}
	,move: function(){
		if(this.isCorrectInitialPosition()){
			newCaboCity.moveBody(this);
		}
	}
	
	//Check if the initial position of the body is correct.
	,isCorrectInitialPosition: function(){
		if(newCaboCity.isRoad(this.from)) return true;
		else return false;
	}
	
	//Check if body can move one more time.
	,canMoveMore: function(){
		return true;
		switch(this.type){
			case d.b.t.inmigrant:
				if(this.to.x == this.destCoor.x && this.to.y == this.destCoor.y)
					return false;
				break;
		}
	}
	,isCorrect: function(){
		var ok = true;
		switch(this.type){
			case d.b.t.inmigrant:
				if(!this.endBuild || !this.predPath)
				break;
		}
	}
	,remove: function(){
		this.el.destroy();
	}
	
	,setStartBuild: function(){
		//do
	}
	,setDestinationBuild: function(destCoor){
		var btl = listBodyTypes[this.type];
		if(!btl.reqDestPos)
			console.log("Error con el destino");
		switch(btl.destType){
			case d.tt.houseZoneTile:
				if( !newCaboCity.isHouse(destCoor) ) {
					console.log("Error con el destino");
					break;
				}
				this.destBuild = destCoor;
				this.path = newCaboCity.toHouseFrom(this.from, destCoor); //Destination coor
				this.dest = this.path[0];
				break;
		}
	}
	,setAmountOf: function(type, amount){
		this.services[type] = amount;
	}
	,setOriginBuild: function(){
		//
	}
});
